﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;
using Debug = UnityEngine.Debug;

namespace XUBuilder
{
    namespace Editor
    {
        internal class XUBuilderiOS
        {
            public static void Build(XUBuilderiOSSetting.Item item)
            {
                GenOutputConfig(item);
                SetPlayerSettings(item);
                if (!item.dontBuild)
                {
                    string projPath = BuildXcode(item);
                    if (Directory.Exists(projPath))
                    {
                        ReplacePlugins(item, projPath);
                        Process.Start(Path.GetDirectoryName(projPath));
                    }
                }
            }

            private static void GenOutputConfig(XUBuilderiOSSetting.Item item)
            {
                OutputConfig outputConfig = new OutputConfig(item.channel, item.package);
                string outputConfigJson = JsonUtility.ToJson(outputConfig, true);
                string savePath = Application.streamingAssetsPath + "/OutputConfig.txt";
                XUBuilderUtil.EnsureFolder(Path.GetDirectoryName(savePath));
                File.WriteAllText(savePath, outputConfigJson);
                Debug.Log(item.gameName + " 生成配置");
            }

            private static void SetPlayerSettings(XUBuilderiOSSetting.Item item)
            {
                PlayerSettings.productName = item.gameName;
                PlayerSettings.applicationIdentifier = item.packageName;
                PlayerSettings.bundleVersion = item.bundleVersion;
                PlayerSettings.iOS.buildNumber = item.bundleVersionCode.ToString();
                Debug.Log(item.gameName + " 设置参数");
            }

            private static string BuildXcode(XUBuilderiOSSetting.Item item)
            {
                //获取首包场景
                List<string> scenes = new List<string>();
                {
                    foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
                    {
                        if (!scene.enabled)
                        {
                            continue;
                        }
                        scenes.Add(scene.path);
                    }
                }

                //设置打包选项
                BuildOptions buildOptions = BuildOptions.None;
                {
                    if (item.development)
                    {
                        buildOptions |= BuildOptions.Development;
                    }
                    if (item.connectProfiler)
                    {
                        buildOptions |= BuildOptions.ConnectWithProfiler;
                    }
                    if (item.deepProfilingSupport)
                    {
                        buildOptions |= BuildOptions.EnableDeepProfilingSupport;
                    }
                }

                //构建路径
                string projPath;
                {
                    StringBuilder projPathBuilder = new StringBuilder();
                    projPathBuilder.Append(GetOutputPath());
                    projPathBuilder.Append("/");
                    projPathBuilder.Append(item.gameName);
                    projPathBuilder.Append("_");
                    projPathBuilder.Append(item.package);
                    projPathBuilder.Append("_");
                    projPathBuilder.Append(DateTime.Now.ToString("G").Replace("/", "-").Replace(":", "-").Replace(" ", "-"));
                    projPath = projPathBuilder.ToString();
                    XUBuilderUtil.ClearFolder(projPath, true);
                    Directory.CreateDirectory(projPath);
                }

                //构建Xcode工程
                {
                    BuildReport report = BuildPipeline.BuildPlayer(scenes.ToArray(), projPath, BuildTarget.iOS, buildOptions);
                    BuildSummary summary = report.summary;

                    if (summary.result == BuildResult.Succeeded)
                    {
                        StringBuilder stringBuilder = new StringBuilder();
                        stringBuilder.AppendLine("构建成功");
                        stringBuilder.AppendLine("开始：" + summary.buildStartedAt);
                        stringBuilder.AppendLine("结束：" + summary.buildEndedAt);
                        stringBuilder.AppendLine("耗时：" + summary.totalTime);
                        stringBuilder.AppendLine("大小：" + XUBuilderUtil.GetSizeString((long)summary.totalSize));
                        Debug.Log(stringBuilder.ToString());
                    }

                    if (summary.result == BuildResult.Failed)
                    {
                        Debug.LogError("构建失败");
                    }
                }

                return projPath;
            }

            private static void ReplacePlugins(XUBuilderiOSSetting.Item item, string projPath)
            {
                string commonDir = GetCommonPath();
                string fromDir = item.GetMainPath();
                string toDir = projPath;
                //清空文件夹
                XUBuilderUtil.EnsureFolder(commonDir);
                XUBuilderUtil.EnsureFolder(fromDir);
                XUBuilderUtil.EnsureFolder(toDir);
                //复制common文件夹
                foreach (var file in Directory.GetFiles(commonDir, "*.*", SearchOption.AllDirectories))
                {
                    string toFile = file.Replace(commonDir, toDir);
                    Directory.CreateDirectory(Path.GetDirectoryName(toFile));
                    File.Copy(file, toFile, true);
                }
                //复制fromDir文件夹
                foreach (var file in Directory.GetFiles(fromDir, "*.*", SearchOption.AllDirectories))
                {
                    string toFile = file.Replace(fromDir, toDir);
                    Directory.CreateDirectory(Path.GetDirectoryName(toFile));
                    File.Copy(file, toFile, true);
                }
                Debug.Log(item.gameName + " 替换Plugins");
            }

            //=============================================================================================================

            public static string GetInputPath()
            {
                string outputPath = Application.dataPath.Replace("Assets", "/BuildInput/iOS");
                XUBuilderUtil.EnsureFolder(outputPath);
                return outputPath;
            }

            public static string GetOutputPath()
            {
                string outputPath = Application.dataPath.Replace("Assets", "/BuildOutput/iOS");
                XUBuilderUtil.EnsureFolder(outputPath);
                return outputPath;
            }

            public static string GetCommonPath()
            {
                string outputPath = Application.dataPath.Replace("Assets", "/BuildInput/iOS/Common");
                XUBuilderUtil.EnsureFolder(outputPath);
                return outputPath;
            }

            //=============================================================================================================

            [Serializable]
            private class OutputConfig
            {
                public ulong channel = 0;
                public ulong package = 0;

                public long ticks = 0;
                public string time = string.Empty;

                public OutputConfig(ulong channel, ulong package)
                {
                    this.channel = channel;
                    this.package = package;

                    DateTime dateTime = DateTime.Now;
                    ticks = dateTime.Ticks;
                    time = dateTime.ToString("F");
                }
            }
        }
    }
}
